#region Copyright(c) 2006 ZO, All right reserved.
// -----------------------------------------------------------------------------
// Copyright(c) 2006 ZO, All right reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   1.  Redistribution of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//   2.  Redistribution in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//   3.  The name of the author may not be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------
#endregion


#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
using ArgumentNullException = ZO.SmartCore.Core.ArgumentNullException;
using ArgumentException = ZO.SmartCore.Core.ArgumentException;
using ArgumentOutOfRangeException = ZO.SmartCore.Core.ArgumentOutOfRangeException;
using ZO.SmartCore.Helpers;
#endregion

namespace ZO.SmartCore.Logger
{
    /// <summary>
    /// Provides support for reading or writing Logs.
    /// </summary>
    /// <typeparam name="TFormatter">Represent log Format</typeparam>
    /// <typeparam name="TProvider">Represent log Provider</typeparam>
    public class Log<TProvider, TFormatter>
        where TProvider : ILogProvider, new()
        where TFormatter : ILogFormat, new()
    {

        #region Constructors
        
        /// <summary>
        /// Initializes a new instance of the <see cref="Log{TProvider, TFormatter}"/> class.
        /// </summary>
        public Log()
        {
            this._Formatter = Activator.CreateInstance<TFormatter>();
            this._Provider = Activator.CreateInstance<TProvider>();
        } // ConfigurationSettings


        /// <summary>
        /// Initializes a new instance of the <see cref="Log{TProvider, TFormatter}"/> class.
        /// </summary>
        /// <param name="formatter">The format of the log.</param>
        /// <param name="provider">log writer provider.</param>
        public Log(TFormatter formatter, TProvider provider)
        {
            if (formatter == null)
            {
                throw new ArgumentNullException("formatter");
            }

            if (provider == null)
            {
                throw new ArgumentNullException("formatter");
            }

            this._Formatter = formatter;
            this._Provider = provider;

           
        } // ConfigurationSettings
        #endregion

        #region Destructor

        #endregion

        #region Fields
 
        private TFormatter _Formatter;

        private TProvider _Provider;

        #endregion

        #region Events

        #endregion

        #region Operators

        #endregion

        #region Properties
     
        /// <summary>
        /// Gets the log file Formatter.
        /// </summary>
        /// <value>The formatter.</value>
        public TFormatter Formatter
        {
            get { return _Formatter; }
        }

        /// <summary>
        /// Gets the log provider.
        /// </summary>
        /// <value>The type.</value>
        public TProvider Provider
        {
            get { return _Provider; }
        }

        #endregion

        #region Methods

        /// <overloads>
        /// Write a new log entry to the default category.
        /// </overloads>
        /// <summary>
        /// Write a new log entry as defined in the <see cref="LogEntry" /> parameter.
        /// </summary>
        /// <example>The following examples demonstrates use of the Write method using
        /// a <see cref="LogEntry" /> type.
        /// <code>
        /// LogEntry log = new LogEntry();
        /// log.Message = "My message body";
        /// log.Severity = TraceEventType.Error;
        /// Log.Write(log);</code></example>
        /// <param name="log">Log entry object to write.</param>
        public void Write(LogEntry log)
        {
            if (log == null)
                return;

            this.Provider.Write(this.Formatter.Format(log));
        }

     
        /// <summary>
        /// Write a new log entry to the default category.
        /// </summary>
        /// <example>The following example demonstrates use of the Write method with
        /// one required parameter, message.
        /// <code>Logger.Write("My message body");</code></example>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        public void Write(string message)
        {
            if (String.IsNullOrEmpty(message))
                return;
            this.Provider.Write(this.Formatter.Format(new LogEntry(message)));
        }


        /// <summary>
        /// Write a new log entry to the default category.
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="args">An Object array containing zero or more objects to format.</param>
        /// <example>The following example demonstrates use of the Write method with
        /// one required parameter, message.
        /// <code>Logger.Write("My message body");</code></example>
        public void Write(string message, params object[] args)
        {
            if (String.IsNullOrEmpty(message))
                return;
            this.Provider.Write(this.Formatter.Format(new LogEntry(StringHelper.Format(message, args))));
        }


        #endregion
    }
}
